package cn.dakaqi.activity.recruit.services;

import cn.dakaqi.activity.apply.service.ActivityApplyService;
import cn.dakaqi.entities.ActivityApply;
import cn.dakaqi.entities.ActivityRecruit;
import cn.dakaqi.entities.ActivityRecruitVolunteer;
import cn.dakaqi.entities.Volunteer;
import cn.dakaqi.log.services.LogService;
import cn.dakaqi.member.service.VolunteerService;
import cn.dakaqi.utils.Clock;
import cn.dakaqi.utils.DKQConstant;
import cn.dakaqi.utils.ErrorCodeMsg;
import cn.dakaqi.utils.exception.ServiceRuntimeException;
import cn.dakaqi.utils.rongYun.PushActivityMesssage;
import cn.dakaqi.utils.rongYun.PushSystemMesssage;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;

import java.util.List;
import java.util.Map;

/**
 * Created by chunyang on 2016/4/19.
 */
@Component(value = "activityRecruitVolunteerService")
@Transactional
public class ActivityRecruitVolunteerServiceImpl implements ActivityRecruitVolunteerService
{
    @Autowired
    ActivityRecruitVolunteerDao activityRecruitVolunteerDao;
    @Autowired
    ActivityRecruitService activityRecruitService;
    @Autowired
    VolunteerService volunteerService;
    @Autowired
    ActivityApplyService activityApplyService;
    @Autowired
    private LogService logService;

    private void saveLog(String message)
    {
        logService.save(400,message);
    }
    @Override
    public void create(String param) throws ServiceRuntimeException
    {
        JSONObject jsonObject = JSON.parseObject(param);
        String memberCode = jsonObject.getString("memberCode");
        Long activityRecruitId = jsonObject.getLong("activityRecruitId");
        String answer = jsonObject.getString("answer");
        String question = jsonObject.getString("question");

        ActivityRecruitVolunteer activityRecruitVolunteer = new ActivityRecruitVolunteer();
        activityRecruitVolunteer.setStatus(DKQConstant.APPLY_STATUS);
        activityRecruitVolunteer.setCreateTime(Clock.DEFAULT.getCurrentDate());
        activityRecruitVolunteer.setActivityRecruit(this.activityRecruitService.findOne(activityRecruitId));

        Volunteer volunteer = this.volunteerService.findByMemberCode(memberCode);
        if(Volunteer.checkInfo(volunteer) == false)
            throw new ServiceRuntimeException(ErrorCodeMsg.USER_INFO_NOT_FULL);

        activityRecruitVolunteer.setVolunteer(volunteer);
        activityRecruitVolunteer.setAnswer(answer);
        activityRecruitVolunteer.setQuestion(question);
        this.save(activityRecruitVolunteer);
    }

    @Override
    public void save(ActivityRecruitVolunteer activityRecruitVolunteer) throws ServiceRuntimeException
    {
        //检查当前用户是否已报名参加本次活动
        ActivityApply aa = activityApplyService.findByVolunteerAndActivity(activityRecruitVolunteer.getVolunteer(), activityRecruitVolunteer.getActivityRecruit().getActivity());
        if(null != aa && aa.getStatus() == DKQConstant.APPLY_STATUS_OK)
        {
            throw new ServiceRuntimeException("您已报名过本次活动,不可以重复报名");
        }

        //检查当前用户是否已申请过当前活动
        ActivityRecruitVolunteer temp = this.isApply(activityRecruitVolunteer.getActivityRecruit().getId(), activityRecruitVolunteer.getVolunteer().getMemberCode());
        if(null != temp)
        {
            if(temp.getStatus() == DKQConstant.APPLY_STATUS)
                throw new ServiceRuntimeException("请耐心等待管理员审核");
            else
            {
                temp.setStatus(DKQConstant.APPLY_STATUS);
                activityRecruitVolunteerDao.save(temp);
                saveLog("用户【" + temp.getVolunteer().getId() + "】报名参加一个活动招募 【" + temp.getId() + "】");
                ActivityRecruit activityRecruit = temp.getActivityRecruit();
                activityRecruit.setApplys(activityRecruit.getApplys() + 1);
                this.activityRecruitService.update(activityRecruit);
                PushActivityMesssage.getInstance().applyActivityRecruit(temp.getActivityRecruit().getActivity().getName(), temp.getVolunteer().getMemberCode());
                PushActivityMesssage.getInstance().verfierActivityRecruit(temp.getVolunteer().getRealName(), temp.getVolunteer().getMemberCode(), temp.getActivityRecruit().getActivity().getName(), temp.getActivityRecruit().getActivity().getMonitor().getMemberCode(), temp.getId());
                return;
            }
        }
        else
        {
            activityRecruitVolunteerDao.save(activityRecruitVolunteer);
            saveLog("用户【" + activityRecruitVolunteer.getVolunteer().getId() + "】报名参加一个活动招募 【" + activityRecruitVolunteer.getId() + "】");
            ActivityRecruit activityRecruit = activityRecruitVolunteer.getActivityRecruit();
            activityRecruit.setApplys(activityRecruit.getApplys() + 1);
            this.activityRecruitService.update(activityRecruit);
            PushActivityMesssage.getInstance().applyActivityRecruit(activityRecruitVolunteer.getActivityRecruit().getActivity().getName(), activityRecruitVolunteer.getVolunteer().getMemberCode());
            PushActivityMesssage.getInstance().verfierActivityRecruit(activityRecruitVolunteer.getVolunteer().getRealName(), activityRecruitVolunteer.getVolunteer().getMemberCode(), activityRecruitVolunteer.getActivityRecruit().getActivity().getName(), activityRecruitVolunteer.getActivityRecruit().getActivity().getMonitor().getMemberCode(), activityRecruitVolunteer.getId());
        }


    }

    @Override
    public void update(ActivityRecruitVolunteer activityRecruitVolunteer) throws ServiceRuntimeException
    {
        activityRecruitVolunteerDao.save(activityRecruitVolunteer);
    }

    @Override
    public Page<ActivityRecruitVolunteer> findAll(Long activityRecruitId,int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activityRecruit.id", new SearchFilter("activityRecruit.id", SearchFilter.Operator.EQ, activityRecruitId));
        Specification<ActivityRecruitVolunteer> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruitVolunteer.class);
        return this.activityRecruitVolunteerDao.findAll(spec,pageRequest);
    }

    @Override
    public Page<ActivityRecruitVolunteer> findByActivityRecruit(Long activityRecruitId, int status,int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);

        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activityRecruit.id", new SearchFilter("activityRecruit.id", SearchFilter.Operator.EQ, activityRecruitId));
        filters.put("status", new SearchFilter("status", SearchFilter.Operator.EQ, status));
        Specification<ActivityRecruitVolunteer> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruitVolunteer.class);
        return this.activityRecruitVolunteerDao.findAll(spec,pageRequest);
    }

    @Override
    public Page<ActivityRecruitVolunteer> findByActivityRecruit(String activityCode, int status, int pageNumber) throws ServiceRuntimeException
    {
        Sort sort = new Sort(Sort.Direction.DESC, "createTime");
        PageRequest pageRequest = new PageRequest(pageNumber - 1, 20, sort);

        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activityRecruit.activity.activityCode", new SearchFilter("activityRecruit.activity.activityCode", SearchFilter.Operator.EQ, activityCode));
        filters.put("status", new SearchFilter("status", SearchFilter.Operator.EQ, status));
        Specification<ActivityRecruitVolunteer> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruitVolunteer.class);
        return this.activityRecruitVolunteerDao.findAll(spec,pageRequest);
    }

    @Override
    public void updateStatus(Long activityRecruitVolunteerId, int status,String refuseCase) throws ServiceRuntimeException
    {
        ActivityRecruitVolunteer activityRecruitVolunteer = this.activityRecruitVolunteerDao.findOne(activityRecruitVolunteerId);
        if(activityRecruitVolunteer != null)
        {
            activityRecruitVolunteer.setStatus(status);
            this.activityRecruitVolunteerDao.save(activityRecruitVolunteer);

            if(status == DKQConstant.APPLY_STATUS_OK)
            {
                //检查当前用户是否已报名参加本次活动
                ActivityApply aa = activityApplyService.findByVolunteerAndActivity(activityRecruitVolunteer.getVolunteer(), activityRecruitVolunteer.getActivityRecruit().getActivity());
                if(null != aa)
                {
                    throw new ServiceRuntimeException("该用户已报名过本次活动,不可以重复报名");
                }
                ActivityApply activityApply = new ActivityApply();
                activityApply.setRole(DKQConstant.ROLES_VOLUNTEER);
                activityApply.setStatus(DKQConstant.APPLY_STATUS_OK);
                activityApply.setVolunteer(activityRecruitVolunteer.getVolunteer());
                activityApply.setCreateTime(Clock.DEFAULT.getCurrentDate());
                activityApply.setActivity(activityRecruitVolunteer.getActivityRecruit().getActivity());
                activityApplyService.save(activityApply);
                saveLog("管理员审核一个活动招募报名记录【" + activityRecruitVolunteer.getId() + "】,审核状态为："+status);
                PushActivityMesssage.getInstance().agreeActivityRecruit(activityApply.getActivity().getName(),activityApply.getVolunteer().getMemberCode());
            }
            else if(status == DKQConstant.APPLY_STATUS_REFUST)
            {
                saveLog("管理员审核一个活动招募报名记录【" + activityRecruitVolunteer.getId() + "】,审核状态为："+status+",拒绝理由为 "+refuseCase);
                activityRecruitVolunteer.setRefuseCase(activityRecruitVolunteer.getRefuseCase()+"|"+refuseCase);
                PushSystemMesssage.getInstance().refuseActivityRecruit(activityRecruitVolunteer.getActivityRecruit().getActivity().getName(),activityRecruitVolunteer.getVolunteer().getMemberCode());
            }
        }
    }

    @Override
    public void updateStatus(String param) throws ServiceRuntimeException
    {
        JSONObject jsonObject = JSON.parseObject(param);
        Long activityRecruitVolunteerId = jsonObject.getLong("activityRecruitVolunteerId");
        String refuseCase = jsonObject.getString("refuseCase");
        int status = jsonObject.getIntValue("status");
        this.updateStatus(activityRecruitVolunteerId,status,refuseCase);
    }

    @Override
    public ActivityRecruitVolunteer findOne(Long activityRecruitVolunteerId) throws ServiceRuntimeException
    {
        return this.activityRecruitVolunteerDao.findOne(activityRecruitVolunteerId);
    }

    @Override
    public ActivityRecruitVolunteer isApply(Long activityRecruitId, String memberCode) throws ServiceRuntimeException
    {
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activityRecruit.id", new SearchFilter("activityRecruit.id", SearchFilter.Operator.EQ, activityRecruitId));
        filters.put("volunteer.memberCode", new SearchFilter("volunteer.memberCode", SearchFilter.Operator.EQ, memberCode));
        Specification<ActivityRecruitVolunteer> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruitVolunteer.class);
        List<ActivityRecruitVolunteer> list =  this.activityRecruitVolunteerDao.findAll(spec);
        if(null != list && list.size()>0)
            return list.get(0);
        return null;
    }

    @Override
    public void exit(String param) throws ServiceRuntimeException
    {
        JSONObject jsonObject = JSON.parseObject(param);
        String memberCode = jsonObject.getString("memberCode");
        Long activityRecruitId = jsonObject.getLong("activityRecruitId");
        exit(isApply(activityRecruitId,memberCode));
    }
    @Override
    public void exit(ActivityRecruitVolunteer activityRecruitVolunteer) throws ServiceRuntimeException
    {
        if(null != activityRecruitVolunteer)
        {
            saveLog(activityRecruitVolunteer.getVolunteer()+"退出"+activityRecruitVolunteer.getActivityRecruit().getActivity().getName()+"招募报名");
            ActivityRecruit activityRecruit = activityRecruitVolunteer.getActivityRecruit();
            activityRecruit.setApplys(activityRecruit.getApplys() - 1);
            this.activityRecruitService.update(activityRecruit);
            activityRecruitVolunteerDao.delete(activityRecruitVolunteer);
        }
    }

    @Override
    public int countForWaite(String activityCode) throws ServiceRuntimeException
    {
        Map<String, SearchFilter> filters = Maps.newHashMap();
        filters.put("activityRecruit.activity.activityCode", new SearchFilter("activityRecruit.activity.activityCode", SearchFilter.Operator.EQ, activityCode));
        filters.put("status", new SearchFilter("status", SearchFilter.Operator.EQ, DKQConstant.APPLY_STATUS));
        Specification<ActivityRecruitVolunteer> spec = DynamicSpecifications.bySearchFilter(filters.values(), ActivityRecruitVolunteer.class);
        List<ActivityRecruitVolunteer> list =  this.activityRecruitVolunteerDao.findAll(spec);
        if(null != list && list.size()>0)
            return list.size();
        return 0;
    }
}
